package com.freshcity.manager
{
	import com.freshcity.IDragDrop;
	import com.greensock.TweenLite;
	import com.greensock.easing.Quint;
	import com.freshcity.event.DragEvent;
	
	import flash.display.*;
	import flash.events.Event;
	import flash.events.MouseEvent;

	public class DragManager
	{
		public var currentDragItem:IDragDrop;
		public var currentDrogItem:IDragDrop;
		private var dragLayer:DisplayObjectContainer;
		private var tempDragItem:DisplayObject;
		private var thumItem:Sprite;
		private var oldMoveOverItem:IDragDrop;
		private var tempCurrentDragItem:IDragDrop;
		private var currentDragSource:Object;
		private var dragBitMapData:BitmapData;
		private static var _instance:DragManager;

		public function DragManager(arg1:flash.display.DisplayObjectContainer)
		{
			if (_instance != null) 
			{
				throw new Error(" DragManager 单例 ");
			}
			this.dragLayer = arg1;
			_instance = this;
		}		
		
		public function startDragItem(arg1:IDragDrop, arg2:BitmapData=null):void
		{
			var loc2:*=null;
			var loc3:*=NaN;
			var loc4:*=NaN;
			if (!arg1.isDragAble)
			{
				return;
			}
			this.dragBitMapData=arg2;
			this.currentDragSource=arg1.dragSource;
			var loc1:*=arg1 as DisplayObject;
			if (DragManager.instance.tempCurrentDragItem == null)
			{
				loc2=loc1.getBounds((arg1 as DisplayObject).parent);
				loc3=loc1.parent.mouseX;
				loc4=loc1.parent.mouseY;
				if (loc3 > loc2.left && loc3 < loc2.right && loc4 > loc2.top && loc4 < loc2.bottom)
				{
					this.doDragItem(loc1);
				}
			}
			return;
		}

		private function doDragItem(arg1:DisplayObject):void
		{
			this.clearThum();
			this.tempDragItem=arg1;
			this.currentDragItem=arg1 as IDragDrop;
			arg1.addEventListener(MouseEvent.MOUSE_MOVE, this.onDragItemMove);
			arg1.addEventListener(MouseEvent.MOUSE_UP, this.onStopDrag);
			return;
		}

		private function onStopDrag(arg1:MouseEvent):void
		{
			this.tempDragItem.removeEventListener(MouseEvent.MOUSE_UP, this.onStopDrag);
			this.tempDragItem.removeEventListener(MouseEvent.MOUSE_MOVE, this.onDragItemMove);
			return;
		}

		private function onDragItemMove(arg1:Event):void
		{
			var loc2:*=null;
			var loc3:*=null;
			var loc4:*=null;
			this.tempDragItem.removeEventListener(MouseEvent.MOUSE_UP, this.onStopDrag);
			this.tempDragItem.removeEventListener(MouseEvent.MOUSE_MOVE, this.onDragItemMove);
			if (this.thumItem == null)
			{
				this.tempDragItem.dispatchEvent(new DragEvent(DragEvent.Event_Start_Drag, this.currentDragItem, this.currentDrogItem, this.currentDragSource, true));
				this.thumItem=new Sprite();
				if (this.dragBitMapData)
				{
					loc2=this.dragBitMapData;
				}
				else
				{
					if (this.tempDragItem.width > 0 && this.tempDragItem.height > 0)
					{
						loc4=this.tempDragItem.getRect(this.dragLayer);
						loc2=new BitmapData(loc4.width, loc4.height, true, 0);
					}
					else
					{
						loc2=new BitmapData(1, 1, true, 0);
					}
					loc2.draw(this.tempDragItem);
				}
				loc3=new Bitmap(loc2);
				this.thumItem.addChild(loc3);
				this.dragLayer.addChild(this.thumItem);
				this.thumItem.x=this.dragLayer.mouseX - this.tempDragItem.mouseX;
				this.thumItem.y=this.dragLayer.mouseY - this.tempDragItem.mouseY;
				this.thumItem.mouseEnabled=false;
				this.thumItem.mouseChildren=false;
				this.thumItem.startDrag();
				this.currentDragItem=this.tempDragItem as IDragDrop;
				this.tempCurrentDragItem=this.currentDragItem;
				this.thumItem.stage.addEventListener(MouseEvent.MOUSE_MOVE, this.onDragItemMove);
				this.thumItem.stage.addEventListener(MouseEvent.MOUSE_UP, this.onDragItemDrop);
			}
			var loc1:*=this.getMainContainer(this.thumItem.dropTarget);
			if (loc1 != this.oldMoveOverItem)
			{
				this.tempCurrentDragItem.dispatchEvent(new DragEvent(DragEvent.Event_Move_Over, this.currentDragItem, this.currentDrogItem, this.currentDragSource, true));
				if (this.oldMoveOverItem)
				{
					this.oldMoveOverItem.dispatchEvent(new DragEvent(DragEvent.Event_Be_Drag_out, this.currentDragItem, this.currentDrogItem, this.currentDragSource, true));
				}
				if (loc1)
				{
					this.currentDrogItem=loc1 as IDragDrop;
					loc1.dispatchEvent(new DragEvent(DragEvent.Event_Be_Drag_over, this.currentDragItem, this.currentDrogItem, this.currentDragSource, true));
					this.oldMoveOverItem=this.currentDrogItem;
				}
			}
			return;
		}

		private function onDragItemDrop(arg1:MouseEvent):void
		{
			var loc1:*=null;
			var loc2:*=null;
			if (this.tempDragItem.hasEventListener(MouseEvent.MOUSE_MOVE))
			{
				this.tempDragItem.removeEventListener(MouseEvent.MOUSE_MOVE, this.onDragItemMove);
			}
			if (this.thumItem && this.thumItem.stage.hasEventListener(MouseEvent.MOUSE_MOVE))
			{
				this.thumItem.stage.removeEventListener(MouseEvent.MOUSE_MOVE, this.onDragItemMove);
			}
			if (this.tempCurrentDragItem == null)
			{
				this.clearThum();
				return;
			}
			else
			{
				loc1=this.thumItem.dropTarget;
				loc2=this.getMainContainer(loc1) as IDragDrop;
				if (loc2 is IDragDrop)
				{
					if (this.canPutIn(this.currentDragItem, loc2))
					{
						this.currentDrogItem=loc2;
						this.currentDragItem.dispatchEvent(new DragEvent(DragEvent.Event_Move_To, this.currentDragItem, this.currentDrogItem, this.currentDragSource, true));
						loc2.dispatchEvent(new DragEvent(DragEvent.Event_Move_In, this.currentDragItem, this.currentDrogItem, this.currentDragSource, true));
						this.thumItem.stopDrag();
						this.clearThum();
						this.tempCurrentDragItem=null;
					}
					else
					{
						this.thumItem.stopDrag();
						this.moveBack();
					}
				}
				else
				{
					this.currentDrogItem=null;
					if (this.tempCurrentDragItem.isThrowAble)
					{
						this.thumItem.stopDrag();
						this.clearThum();
						this.tempCurrentDragItem.dispatchEvent(new DragEvent(DragEvent.Event_Throw_goods, this.currentDragItem, this.currentDrogItem, this.currentDragSource, true));
						this.tempCurrentDragItem=null;
					}
					else
					{
						this.thumItem.stopDrag();
						this.moveBack();
						this.tempCurrentDragItem=null;
					}
				}
			}
			return;
		}

		private function moveBack():void
		{
			var loc1:*=null;
			if (this.currentDragItem)
			{
				loc1=(this.currentDragItem as DisplayObject).getBounds(this.dragLayer);
				TweenLite.to(this.thumItem, 0.2, {"x": loc1.left, "y": loc1.top, "onComplete": this.moveBackEnd, "ease": Quint.easeOut});
			}
			else
			{
				this.moveBackEnd();
			}
			return;
		}

		private function moveBackEnd():void
		{
			this.tempCurrentDragItem=null;
			this.clearThum();
			return;
		}

		private function clearThum():void
		{
			if (this.thumItem)
			{
				if (this.thumItem.hasEventListener(MouseEvent.MOUSE_MOVE))
				{
					this.thumItem.removeEventListener(MouseEvent.MOUSE_MOVE, this.onDragItemMove);
				}
				if (this.thumItem.hasEventListener(MouseEvent.MOUSE_UP))
				{
					this.thumItem.removeEventListener(MouseEvent.MOUSE_UP, this.onDragItemDrop);
				}
				if (this.dragLayer.contains(this.thumItem))
				{
					this.dragLayer.removeChild(this.thumItem);
				}
				this.thumItem=null;
			}
			return;
		}

		private function canPutIn(arg1:IDragDrop, arg2:IDragDrop):Boolean
		{
			return arg2.canDrop(arg1, arg2);
		}

		private function getMainContainer(arg1:DisplayObject):DisplayObject
		{
			if (!arg1)
			{
				return null;
			}
			if (arg1 is IDragDrop && (arg1 as IDragDrop).isDropAble)
			{
				return arg1;
			}
			if (arg1.parent is IDragDrop && (arg1.parent as IDragDrop).isDropAble)
			{
				return arg1.parent;
			}
			if (arg1.parent is Stage)
			{
				return null;
			}
			return this.getMainContainer(arg1.parent);
		}

		public static function get instance():DragManager
		{
			if (!_instance)
			{
				throw new Error("DragManager 尚未初始化");
			}
			return _instance;
		}

		public static function init(arg1:DisplayObjectContainer):void
		{
			if (_instance == null)
			{
				_instance=new DragManager(arg1);
			}
			return;
		}

	}
}

